﻿namespace NTLib.WPF.Themes
{
    using Application.Themes;
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;

    /// <summary>
    /// 
    /// </summary>
    /// <seealso cref="System.Windows.DependencyObject" />
    public sealed class ThemeContainer : DependencyObject
    {
        #region Ctor

        /// <summary>
        /// Initializes a new instance of the <see cref="ThemeContainer"/> class.
        /// </summary>
        public ThemeContainer()
        {
            Themes = new ObservableCollection<ThemeDictionary>();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the themes.
        /// </summary>
        public ObservableCollection<ThemeDictionary> Themes
        {
            get { return (ObservableCollection<ThemeDictionary>)GetValue(ThemesProperty); }
            set { SetValue(ThemesProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Themes.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ThemesProperty =
            DependencyProperty.Register("Themes", typeof(ObservableCollection<ThemeDictionary>), typeof(ThemeContainer), new PropertyMetadata(null, CollectionThemeChanged)); //new ObservableCollection<ThemeDictionary>()

        #endregion

        #region Methods

        /// <summary>
        /// Collections the theme changed.
        /// </summary>
        /// <param name="dp">The dp.</param>
        /// <param name="args">The <see cref="System.Windows.DependencyPropertyChangedEventArgs" /> instance containing the event data.</param>
        private static void CollectionThemeChanged(DependencyObject dp, DependencyPropertyChangedEventArgs args)
        {
            if (args.OldValue != null)
            {
                var collection = args.OldValue as ObservableCollection<ThemeDictionary>;
                collection.CollectionChanged -= Collection_CollectionChanged;

                foreach (var c in collection)
                    ThemeManager.UnRegisterTheme(c);
            }

            if (args.NewValue != null)
            {
                var collection = args.NewValue as ObservableCollection<ThemeDictionary>;
                foreach (var c in collection)
                    ThemeManager.RegisterTheme(c);

                collection.CollectionChanged += Collection_CollectionChanged;
            }
        }

        /// <summary>
        /// Handles the CollectionChanged event of the Collection control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Collections.Specialized.NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private static void Collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            var action = e.Action;
            if (e.Action == NotifyCollectionChangedAction.Replace)
            {
                Collection_CollectionChanged(sender, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, e.OldItems, e.OldStartingIndex));
                Collection_CollectionChanged(sender, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, e.NewItems, e.NewStartingIndex));
                return;
            }
            switch (action)
            {
                case NotifyCollectionChangedAction.Add:
                    for (int i = 0; i < e.NewItems.Count; ++i)
                        ThemeManager.RegisterTheme(e.NewItems[i] as ThemeDictionary);
                    break;
                case NotifyCollectionChangedAction.Reset:
                case NotifyCollectionChangedAction.Remove:
                    for (int i = 0; i < e.OldItems.Count; ++i)
                        ThemeManager.UnRegisterTheme(e.OldItems[i] as ThemeDictionary);
                    break;
                default:
                    break;
            }
        }

        #endregion
    }
}
